package com.zmn.oms.services.impl.report;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.base.oms.common.model.es.orderpay.EsOrderPay;
import com.zmn.base.plat.engine.common.constant.DubboConsts;
import com.zmn.base.product.common.dto.categ.CategServDRO;
import com.zmn.base.product.common.query.categ.ForeignCategServQuery;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategServListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.OptionData;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.oms.business.impl.base.AbstractListEsQueryServiceImpl;
import com.zmn.oms.business.interfaces.es.OrderPayEsBService;
import com.zmn.oms.common.constant.OrderPayConsts;
import com.zmn.oms.model.entity.report.EsReportPayQuery;
import com.zmn.oms.model.vo.report.ReportPayDetailVO;
import com.zmn.oms.model.vo.report.ReportPayVO;
import com.zmn.oms.services.interfaces.report.ReportPayService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ：SongWeidong
 * @date ：2021/5/10 17:42
 * @description：支付明细报表
 */
@Slf4j
@Service
public class ReportPayServiceImpl extends AbstractListEsQueryServiceImpl implements ReportPayService {

    private static String KEY_FORMAT = "%s&%s";

    @Autowired
    private OrderPayEsBService orderPayEsBService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private CompanyListRemoteService companyListRemoteService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private CategServListRemoteService categServListRemoteService;

    /**
     * 支付明细详情
     *
     * @return
     */
    @Override
    public List<ReportPayDetailVO> listDetailByQuery(EsReportPayQuery query) {

        NativeSearchQuery searchQuery = super.builderSearchQuery(query);

        List<EsOrderPay> esOrderPays = orderPayEsBService.listPageByQuery(searchQuery);
        query.setTotalCount(searchQuery.getMaxResults());
        List<ReportPayDetailVO> retList = Lists.newArrayListWithCapacity(esOrderPays.size());

        esOrderPays.forEach(esOrderPay -> {
            ReportPayDetailVO detailVO = new ReportPayDetailVO();
            BeanUtils.copyProperties(esOrderPay, detailVO);
            detailVO.setTradeTypeName(detailVO.getTradeType() == PayConsts.PAY_TRADE_TYPE_REFUND ? "退款" : "支付");
            if (!Objects.equals(detailVO.getAmountType(), GlobalConsts.NONE)) {
                detailVO.setAmountTypeName(OrderPayConsts.getAmountTypeName(detailVO.getAmountType()));
            }
            if (Objects.equals(detailVO.getTradeType(), PayConsts.PAY_TRADE_TYPE_REFUND)) {
                detailVO.setAmount(-detailVO.getAmount());
            }
            retList.add(detailVO);
        });

        return retList;
    }

    @Override
    public List<ReportPayVO> listGroupByCompanyFromPay(EsReportPayQuery query) {
        NativeSearchQuery searchQuery = super.builderSearchQuery(query);

        // 分组
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(query.getGroupFiled()).field(query.getGroupFiled());

        // 应收
        BoolQueryBuilder sumBuilder = QueryBuilders.boolQuery();
        sumBuilder.filter(QueryBuilders.termQuery("tradeType", PayConsts.PAY_TRADE_TYPE_INTIME));
        sumBuilder.filter(QueryBuilders.termQuery("payStatus", PayConsts.PAY_STATUS_DONE));
        FilterAggregationBuilder sumAmount = AggregationBuilders.filter("sumAmount", sumBuilder)
                .subAggregation(AggregationBuilders.sum("amount").field("amount"));
        termsAggregationBuilder.subAggregation(sumAmount);

        BoolQueryBuilder duplicateBuilder = QueryBuilders.boolQuery();
        duplicateBuilder.filter(QueryBuilders.termQuery("duplicate", GlobalConsts.YES));
        FilterAggregationBuilder duplicateFilterBuilder = AggregationBuilders.filter("duplicateAmount", duplicateBuilder)
                .subAggregation(AggregationBuilders.sum("amount").field("amount"));
        termsAggregationBuilder.subAggregation(duplicateFilterBuilder);

        // 按照payChannelId分组
        FilterAggregationBuilder filter_pay_channel = AggregationBuilders.filter("payChannelAmount", sumBuilder)
                .subAggregation(AggregationBuilders.sum("amount").field("amount"));
        TermsAggregationBuilder masterPayChannelTerms = AggregationBuilders.terms("payChannelId").field("payChannelId");
        masterPayChannelTerms.subAggregation(filter_pay_channel);

        // 收款聚合-为了获取银联分项金额 按照目标渠道、目标支付类型聚合
        TermsAggregationBuilder chinaumsTermsAggr = AggregationBuilders.terms("payTargetChannelId").field("payTargetChannelId");
        TermsAggregationBuilder chinaumsPayTypeTermsAggr = AggregationBuilders.terms("payTargetType").field("payTargetType");
        chinaumsPayTypeTermsAggr.subAggregation(AggregationBuilders.sum("amount").field("amount"));
        chinaumsTermsAggr.subAggregation(chinaumsPayTypeTermsAggr);
        masterPayChannelTerms.subAggregation(chinaumsTermsAggr);
        termsAggregationBuilder.subAggregation(masterPayChannelTerms);

        // 现金（现金就是退款单的退款金额）
        BoolQueryBuilder refundBuilder = QueryBuilders.boolQuery();
        refundBuilder.filter(QueryBuilders.termQuery("tradeType", PayConsts.PAY_TRADE_TYPE_REFUND));
        //refundBuilder.filter(QueryBuilders.termQuery("payStatus", PayConsts.REFUND_STATUS_DONE));
        FilterAggregationBuilder filter_refund = AggregationBuilders.filter("filterCashAmount", refundBuilder).
                subAggregation(AggregationBuilders.sum("amount").field("amount"));
        termsAggregationBuilder.subAggregation(filter_refund);

        // 金额降序
        termsAggregationBuilder.order(BucketOrder.aggregation("sumAmount", false)).size(10000);

        searchQuery.addAggregation(termsAggregationBuilder);
        Aggregations aggregationsAll = orderPayEsBService.getAggregationsByQuery(searchQuery);
        ParsedLongTerms terms = aggregationsAll.get(query.getGroupFiled());
        List<? extends Terms.Bucket> buckets = terms.getBuckets();

        List<ReportPayVO> list = Lists.newArrayList();
        if (CollectionUtil.isNullOrEmpty(buckets)) {
            return list;
        }

        buckets.forEach(bucket -> {
            Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();

            ReportPayVO reportVO = new ReportPayVO();
            if (Objects.equals(query.getGroupFiled(), "companyId")) {
                reportVO.setCompanyId(bucket.getKeyAsNumber().intValue());
            } else {
                reportVO.setServCategId(bucket.getKeyAsNumber().intValue());
            }

            // 应收总计
            ParsedFilter sumFilter = (ParsedFilter) stringAggregationMap.get("sumAmount");
            long totalAmount = (long) ((ParsedSum) sumFilter.getAggregations().get("amount")).getValue();
            //long totalAmount = (long) ((InternalSum) stringAggregationMap.get("amount")).getValue();
            reportVO.setTotalAmount(totalAmount);

            // 重复支付
            ParsedFilter duplicateFilter = (ParsedFilter) stringAggregationMap.get("duplicateAmount");
            long duplicateAmount = (long) ((ParsedSum) duplicateFilter.getAggregations().get("amount")).getValue();
            //long totalAmount = (long) ((InternalSum) stringAggregationMap.get("amount")).getValue();
            reportVO.setDuplicateAmount(duplicateAmount);

            // 现金支付 = 退款单的退款金额
            ParsedFilter internalFilter = (ParsedFilter) stringAggregationMap.get("filterCashAmount");
            long cashAmount = (long) ((ParsedSum) internalFilter.getAggregations().get("amount")).getValue();
            reportVO.setCashAmount(-cashAmount);

            // 实收总计
            reportVO.setRealityTotalAmount(totalAmount - cashAmount);

            // 工程师收款金额
            ParsedLongTerms payTerms = (ParsedLongTerms) stringAggregationMap.get("payChannelId");
            List<? extends Terms.Bucket> payTermsBuckets = payTerms.getBuckets();
            Map<String, Long> payChannelMap = new HashMap<>();
            Map<String, Long> chinaumsPayChannelMap = new HashMap<>();

            payTermsBuckets.forEach(amountBucket -> {

                Map<String, Aggregation> payChannelAggregationMap = amountBucket.getAggregations().asMap();
                String payChannelId = amountBucket.getKeyAsString();
                Aggregations aggregations = amountBucket.getAggregations();

                ParsedFilter payChannelFilter = (ParsedFilter) payChannelAggregationMap.get("payChannelAmount");
                long masterAmount = (long) ((ParsedSum) payChannelFilter.getAggregations().get("amount")).getValue();

                //long masterAmount = (long) ((InternalSum) aggregations.get("amount")).getValue();
                // 处理各种方式支付金额

                payChannelMap.put(payChannelId, masterAmount);
                // 处理银联金额信息
                if (payChannelId.equals(String.valueOf(PayConsts.PAY_CHANNEL_THIRD_CHINAUMS))) {
                    // 取得 payTargetChannelId 聚合
                    ParsedLongTerms chinaumsPayTerms = (ParsedLongTerms) aggregations.asMap().get("payTargetChannelId");
                    List<? extends Terms.Bucket> chinaumsPayTermsBuckets = chinaumsPayTerms.getBuckets();
                    chinaumsPayTermsBuckets.forEach(payTargetChannelBucket -> {
                        // 目标渠道ID
                        String payTargetChannelId = payTargetChannelBucket.getKeyAsString();
                        Aggregations aggr = payTargetChannelBucket.getAggregations();
                        // 取得 payTargetChannelId 聚合
                        ParsedLongTerms chinaumsPayTypeTerms = (ParsedLongTerms) aggr.asMap().get("payTargetType");
                        List<? extends Terms.Bucket> chinaumsPayTypeTermsBuckets = chinaumsPayTypeTerms.getBuckets();
                        chinaumsPayTypeTermsBuckets.forEach(payTargetTypeChannelBucket -> {
                            String payTargetType = payTargetTypeChannelBucket.getKeyAsString();
                            Aggregations typeAggr = payTargetTypeChannelBucket.getAggregations();
                            // 获取师傅收款金额
                            long payTargetMasterAmount = (long) ((ParsedSum) typeAggr.get("amount")).getValue();

                            // 获取银联支付key
                            String key = getKey(payTargetChannelId, payTargetType);

                            chinaumsPayChannelMap.put(key, payTargetMasterAmount);
                        });
                    });
                }
            });

            // 保存结果
            reportVO.setAlipayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_ALIPAY))).orElse(0L));
            reportVO.setWeixinpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_WEIXINPAY))).orElse(0L));
            reportVO.setIcbcpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_ICBCPAY))).orElse(0L));
            reportVO.setBankpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BANKTRANSFER))).orElse(0L));
            reportVO.setYipayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_YIPAY))).orElse(0L));
            Long bAmount = Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BALANCEAMOUNT))).orElse(0L) +
                    Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_CREDIT))).orElse(0L);
            reportVO.setBalancepayAmount(bAmount);
            reportVO.setChannelpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_CHANNEL))).orElse(0L));
            reportVO.setChinaumsQRAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.valueOf(PayConsts.PAY_TYPE_QR))).orElse(0L));
            reportVO.setChinaumsAlipayAppAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.format(KEY_FORMAT, PayConsts.PAY_CHANNEL_PLATFORM_ALIPAY, PayConsts.PAY_TYPE_APP))).orElse(0L));
            reportVO.setChinaumsWechatpayAppAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.format(KEY_FORMAT, PayConsts.PAY_CHANNEL_PLATFORM_WEIXINPAY, PayConsts.PAY_TYPE_APP))).orElse(0L));
            reportVO.setEciticAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_THIRD_ECITIC))).orElse(0L));
            reportVO.setBaidupayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BAIDU))).orElse(0L));
            reportVO.setKuaishoupayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_KUAISHOU))).orElse(0L));
            reportVO.setWarrantyAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_DEPOSIT))).orElse(0L));

            list.add(reportVO);
        });

        if (Objects.equals(query.getGroupFiled(), "companyId")) {
            // 设置公司名称
            List<Integer> companyIds = list.stream().map(ReportPayVO::getCompanyId).distinct().collect(Collectors.toList());
            ResponseDTO<OptionData<Integer>> companyRemote = companyListRemoteService.listOptionByCompanyIds(companyIds);
            if (companyRemote.isSuccess() && Objects.nonNull(companyRemote.getData()) && CollectionUtil.isNotNullOrEmpty(companyRemote.getData().getOptions())) {
                Map<Integer, String> companyMap = companyRemote.getData().getOptions().stream().collect(Collectors.toMap(Option<Integer>::getValue, Option::getLabel));
                list.forEach(e -> {
                    if (companyMap.containsKey(e.getCompanyId())) {
                        e.setCompanyName(companyMap.get(e.getCompanyId()));
                    } else {
                        e.setCompanyName(String.valueOf(e.getCompanyId()));
                    }
                });
            } else {
                list.forEach(e -> e.setCompanyName(String.valueOf(e.getCompanyId())));
            }
        } else {
            // 设置服务分类名称
            ResponseDTO<List<CategServDRO>> responseDTO = categServListRemoteService.listByQuery(new ForeignCategServQuery());
            log.info("批量查询服务分类出参：【{}】", JSON.toJSONString(responseDTO));
            if (responseDTO.isSuccess() && CollectionUtil.isNotNullOrEmpty(responseDTO.getData())) {
                Map<Integer, String> servCategMap = responseDTO.getData().stream().collect(Collectors.toMap(CategServDRO::getServCategId, CategServDRO::getEcServCategName));
                list.forEach(e -> {
                    if (servCategMap.containsKey(e.getServCategId())) {
                        e.setServCategName(servCategMap.get(e.getServCategId()));
                    } else {
                        e.setServCategName(String.valueOf(e.getServCategId()));
                    }
                });
            } else {
                list.forEach(e -> e.setServCategName(String.valueOf(e.getServCategId())));
            }
        }
        return list;
    }

    @Override
    public List<ReportPayVO> listRefundGroupByCompanyFromPay(EsReportPayQuery query) {
        NativeSearchQuery searchQuery = super.builderSearchQuery(query);

        // 分组
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms(query.getGroupFiled()).field(query.getGroupFiled());

        // 应收
        termsAggregationBuilder.subAggregation(AggregationBuilders.sum("amount").field("amount"));

        // 按照payChannelId分组
        TermsAggregationBuilder masterPayChannelTerms = AggregationBuilders.terms("payChannelId").field("payChannelId");
        masterPayChannelTerms.subAggregation(AggregationBuilders.sum("amount").field("amount"));

        // 收款聚合-为了获取银联分项金额 按照目标渠道、目标支付类型聚合
        TermsAggregationBuilder chinaumsTermsAggr = AggregationBuilders.terms("payTargetChannelId").field("payTargetChannelId");
        TermsAggregationBuilder chinaumsPayTypeTermsAggr = AggregationBuilders.terms("payTargetType").field("payTargetType");
        chinaumsPayTypeTermsAggr.subAggregation(AggregationBuilders.sum("amount").field("amount"));
        chinaumsTermsAggr.subAggregation(chinaumsPayTypeTermsAggr);
        masterPayChannelTerms.subAggregation(chinaumsTermsAggr);
        termsAggregationBuilder.subAggregation(masterPayChannelTerms);

        // 金额降序
        termsAggregationBuilder.order(BucketOrder.aggregation("amount", false)).size(10000);

        searchQuery.addAggregation(termsAggregationBuilder);
        Aggregations aggregationsAll = orderPayEsBService.getAggregationsByQuery(searchQuery);
        ParsedLongTerms terms = aggregationsAll.get(query.getGroupFiled());
        List<? extends Terms.Bucket> buckets = terms.getBuckets();

        List<ReportPayVO> list = Lists.newArrayList();
        if (CollectionUtil.isNullOrEmpty(buckets)) {
            return list;
        }

        buckets.forEach(bucket -> {
            Map<String, Aggregation> stringAggregationMap = bucket.getAggregations().asMap();

            ReportPayVO reportVO = new ReportPayVO();
            if (Objects.equals(query.getGroupFiled(), "companyId")) {
                reportVO.setCompanyId(bucket.getKeyAsNumber().intValue());
            } else {
                reportVO.setServCategId(bucket.getKeyAsNumber().intValue());
            }

            // 应收总计
            long totalAmount = (long) ((ParsedSum) stringAggregationMap.get("amount")).getValue();
            reportVO.setTotalAmount(totalAmount);

            // 工程师收款金额
            ParsedLongTerms payTerms = (ParsedLongTerms) stringAggregationMap.get("payChannelId");
            List<? extends Terms.Bucket> payTermsBuckets = payTerms.getBuckets();
            Map<String, Long> payChannelMap = new HashMap<>();
            Map<String, Long> chinaumsPayChannelMap = new HashMap<>();

            payTermsBuckets.forEach(amountBucket -> {

                //Map<String, Aggregation> payChannelAggregationMap = amountBucket.getAggregations().asMap();
                String payChannelId = amountBucket.getKeyAsString();
                Aggregations aggregations = amountBucket.getAggregations();

                //InternalFilter payChannelFilter = (InternalFilter) payChannelAggregationMap.get("payChannelAmount");
                long masterAmount = (long) ((ParsedSum) aggregations.get("amount")).getValue();

                //long masterAmount = (long) ((InternalSum) aggregations.get("amount")).getValue();
                // 处理各种方式支付金额

                payChannelMap.put(payChannelId, masterAmount);
                // 处理银联金额信息
                if (payChannelId.equals(String.valueOf(PayConsts.PAY_CHANNEL_THIRD_CHINAUMS))) {
                    // 取得 payTargetChannelId 聚合
                    ParsedLongTerms chinaumsPayTerms = (ParsedLongTerms) aggregations.asMap().get("payTargetChannelId");
                    List<? extends Terms.Bucket> chinaumsPayTermsBuckets = chinaumsPayTerms.getBuckets();
                    chinaumsPayTermsBuckets.forEach(payTargetChannelBucket -> {
                        // 目标渠道ID
                        String payTargetChannelId = payTargetChannelBucket.getKeyAsString();
                        Aggregations aggr = payTargetChannelBucket.getAggregations();
                        // 取得 payTargetChannelId 聚合
                        ParsedLongTerms chinaumsPayTypeTerms = (ParsedLongTerms) aggr.asMap().get("payTargetType");
                        List<? extends Terms.Bucket> chinaumsPayTypeTermsBuckets = chinaumsPayTypeTerms.getBuckets();
                        chinaumsPayTypeTermsBuckets.forEach(payTargetTypeChannelBucket -> {
                            String payTargetType = payTargetTypeChannelBucket.getKeyAsString();
                            Aggregations typeAggr = payTargetTypeChannelBucket.getAggregations();
                            // 获取师傅收款金额
                            long payTargetMasterAmount = (long) ((ParsedSum) typeAggr.get("amount")).getValue();

                            // 获取银联支付key
                            String key = getKey(payTargetChannelId, payTargetType);

                            chinaumsPayChannelMap.put(key, payTargetMasterAmount);
                        });
                    });
                }
            });

            // 保存结果
            reportVO.setAlipayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_ALIPAY))).orElse(0L));
            reportVO.setWeixinpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_WEIXINPAY))).orElse(0L));
            reportVO.setIcbcpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_ICBCPAY))).orElse(0L));
            reportVO.setBankpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BANKTRANSFER))).orElse(0L));
            reportVO.setYipayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_YIPAY))).orElse(0L));
            Long bAmount = Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BALANCEAMOUNT))).orElse(0L) +
                    Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_CREDIT))).orElse(0L);
            reportVO.setBalancepayAmount(bAmount);
            reportVO.setChannelpayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_CHANNEL))).orElse(0L));
            reportVO.setChinaumsQRAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.valueOf(PayConsts.PAY_TYPE_QR))).orElse(0L));
            reportVO.setChinaumsAlipayAppAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.format(KEY_FORMAT, PayConsts.PAY_CHANNEL_PLATFORM_ALIPAY, PayConsts.PAY_TYPE_APP))).orElse(0L));
            reportVO.setChinaumsWechatpayAppAmount(Optional.ofNullable(chinaumsPayChannelMap.get(String.format(KEY_FORMAT, PayConsts.PAY_CHANNEL_PLATFORM_WEIXINPAY, PayConsts.PAY_TYPE_APP))).orElse(0L));
            reportVO.setEciticAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_THIRD_ECITIC))).orElse(0L));
            reportVO.setBaidupayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_BAIDU))).orElse(0L));
            reportVO.setKuaishoupayAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_KUAISHOU))).orElse(0L));
            reportVO.setCashAmount(Optional.ofNullable(payChannelMap.get(String.valueOf(PayConsts.PAY_CHANNEL_PLATFORM_OFFLINE))).orElse(0L));
            list.add(reportVO);
        });

        if (Objects.equals(query.getGroupFiled(), "companyId")) {
            // 设置公司名称
            List<Integer> companyIds = list.stream().map(ReportPayVO::getCompanyId).distinct().collect(Collectors.toList());
            ResponseDTO<OptionData<Integer>> companyRemote = companyListRemoteService.listOptionByCompanyIds(companyIds);
            if (companyRemote.isSuccess() && Objects.nonNull(companyRemote.getData()) && CollectionUtil.isNotNullOrEmpty(companyRemote.getData().getOptions())) {
                Map<Integer, String> companyMap = companyRemote.getData().getOptions().stream().collect(Collectors.toMap(Option<Integer>::getValue, Option::getLabel));
                list.forEach(e -> {
                    if (companyMap.containsKey(e.getCompanyId())) {
                        e.setCompanyName(companyMap.get(e.getCompanyId()));
                    } else {
                        e.setCompanyName(String.valueOf(e.getCompanyId()));
                    }
                });
            } else {
                list.forEach(e -> e.setCompanyName(String.valueOf(e.getCompanyId())));
            }
        } else {
            // 设置服务分类名称
            ResponseDTO<List<CategServDRO>> responseDTO = categServListRemoteService.listByQuery(new ForeignCategServQuery());
            if (responseDTO.isSuccess() && CollectionUtil.isNotNullOrEmpty(responseDTO.getData())) {
                Map<Integer, String> servCategMap = responseDTO.getData().stream().collect(Collectors.toMap(CategServDRO::getServCategId, CategServDRO::getEcServCategName));
                list.forEach(e -> {
                    if (servCategMap.containsKey(e.getServCategId())) {
                        e.setServCategName(servCategMap.get(e.getServCategId()));
                    } else {
                        e.setServCategName(String.valueOf(e.getServCategId()));
                    }
                });
            } else {
                list.forEach(e -> e.setServCategName(String.valueOf(e.getServCategId())));
            }
        }
        return list;
    }

    /**
     * 获取银联支付下属key
     */
    private String getKey(String payTargetChannelId, String payTargetType) {
        if (payTargetType.equals(String.valueOf(PayConsts.PAY_TYPE_QR))) {
            return payTargetType;
        } else {
            // 以channelId + type 作为key，方便取出特定的组合
            return String.format(KEY_FORMAT, payTargetChannelId, payTargetType);
        }
    }

}
